--AceLibrary("AceConsole-2.0"):PrintLiteral(itembutton)

local AceOO = AceLibrary("AceOO-2.0")
local L = AceLibrary("AceLocale-2.2"):new("DKPmon_Recoil")

local Recoil = AceOO.Class(DKPmon_DKP_BaseClass)

local dewdrop = AceLibrary("Dewdrop-2.0")

-- CustomInfo (For DKPmon_eqDKP)
local custom = {}
custom.poolnames = {
	[1] = "DKP"
}
custom.numpools = 1
DKPmon.CustomInfo:Register(custom, "Recoil")

--[[
  dkpInfo table:
    cost -- number; the cost of the item
    bidplaced -- bool; true if we placed a bid, else false
    bidmodifier -- number; nil -> no bid, else random modifier for my bid
  cost & bidmodifier are filled in and passed from Bidder
]]

--[[
Initialize()
Description:
  Initialize the DKP system. Effectively called from within the OnEnable() function of DKPmon
Input:
  None
Returns:
  None
]]
function Recoil.prototype:Initialize()
   local mydb = DKPmon.DKP:GetDB("Recoil")
   if mydb.qualthreshold == nil then
      mydb.qualthreshold = 4 -- Epic
   end
   if mydb.ctrt == nil then
      mydb.ctrt = false
   end
end

--[[
GetItemInfo(iteminfo)
Description:
  Given information on an item, check if the item is allowed to be bid on (meets quality requirements, is in a database, etc)
  and get the DKP information for the item.
Input:
  iteminfo -- ItemInfo table minus allowed & dkpinfo fields
Returns:
  allowed, dkpinfo
    allowed -- boolean or nil;  
      nil (item shouldn't be bid on), 
      false (item is okay, but more info is needed for it. So, the item can be added to the list, but bidding cannot be opened until the info is filled in)
      true (item's good to go)
    dkpinfo -- table; information on this item's cost, etc. (whatever's needed by the DKP system to know how many points to charge for the item). nil if allowed = nil
]]
function Recoil.prototype:GetItemInfo(iteminfo)
   local mydb = DKPmon.DKP:GetDB("Recoil")
   if iteminfo.quality < mydb.qualthreshold then return nil,nil end
   
   local dkpinfo, allowed = {}, true
   -- Get the item value
   dkpinfo.cost = Recoil:ilvlDKP(iteminfo.link)
   
   -- If the cost is zero we need to request it
   if dkpinfo.cost == 0 and DKPMon_Recoil_Static[iteminfo.name] == nil then
   	allowed = false
   end
   
   return allowed, dkpinfo
end

--[[
FillTooltip(dkpinfo)
Description:
  Called when an item in the Looting Window is moused over to add the DKP-system specific information to the GameTooltip for the moused over item
Input:
  dkpinfo -- table; same table returned from self:GetItemInfo()
Returns:
  Nothing
]]
function Recoil.prototype:FillTooltip(dkpinfo)
   GameTooltip:AddLine(" ")
   GameTooltip:AddLine(string.format(L["DKP = %g"], dkpinfo.cost), 1.0, 0.819, 0.0)
end

--[[
AddDistributionActionOptions(dewOptions, bidstate)
Description:
  Called when the "Actions" button in the loot distribution window is pressed.
  This call allowed the DKP system to add any DKP-system specific options it might like to the action menu.
Input:
  dewOptions -- the AceOptions table to add to
  bidstate -- the current bidstate.
Returns:
  None
]]
function Recoil.prototype:AddDistributionActionOptions(dewOptions, bidstate)
end

--[[
BuildWinnerSelectList(itembutton, dewOptions, iteminfo)
Description:
  Build the list of item bidders to select a winner from.
  Note: the "Disenchant" and "Guild bank" options will already be in the list.
Input:
  itembutton -- LootItem; lootitem class/table that's associated with the item passed.
  dewOptions -- table; dewOptions table to add the list to
  dkpinfo -- table; information about the item for the DKP system
  bidders -- table; indexed by number, starting at 1. Each entry is a table of the form: { name = string, dkpinfo = table }
    where "name" is the name of the player that placed the bid, and dkpinfo is the information about their bid
Returns:
  None
]]
function Recoil.prototype:BuildWinnerSelectList(itembutton, dewOptions, dkpinfo, bidders)  
   -- Sort the bidders table in order of DKP standing
   table.sort(bidders, function(n1, n2) 
   				p1 = self:GetPlayerPoints(DKPmon.RaidRoster:GetPlayerInfo(n1.name).bidchar.name, 1)
   				p2 = self:GetPlayerPoints(DKPmon.RaidRoster:GetPlayerInfo(n2.name).bidchar.name, 1)   				
   				return p1 > p2
   			end)
   -- Add the bidders to the output
   local i, nametab
   for i, nametab in ipairs(bidders) do
      local bidderinfo = DKPmon.RaidRoster:GetPlayerInfo(nametab.name) -- information about the player who placed this bid
      if bidderinfo == nil then
	 DKPmon:Print(string.format(L["Error -- player %s has bid on this item but has never been in the raid! Not listing them."], nametab.name))
      else
	 local playerpnts = self:GetPlayerPoints(bidderinfo.bidchar.name, 1)
	 local namestr	 
	 if nametab.name == bidderinfo.bidchar.name then
	    namestr = string.format("|cff%s%s|r(%g + %d)", bidderinfo.char.classhex, nametab.name, playerpnts, nametab.bidmodifier)
	 else
	    namestr = string.format("|cff%s%s|r[|cff%s%s|r](%g + %d)", bidderinfo.char.classhex, nametab.name, bidderinfo.bidchar.classhex, bidderinfo.bidchar.name, playerpnts, nametab.bidmodifier)
	 end
	 dewOptions.args[string.format("%d", i)] = { 
	    type = 'execute', name = namestr, order = 35000 - playerpnts, 
	    desc = string.format(L["Select %s to win the item"], nametab.name),
	    func = function() itembutton.bidinfo.winner = nametab.name; itembutton:UpdateStatusText(); end
	 }
      end
   end
end


StaticPopupDialogs["DKPMON_Recoil_CONFIRM_SETITEMVALUE"] = {
   text = "", -- will be assigned by creater
   button1 = L["Yes"],
   button2 = L["No"],
   OnAccept = nil, -- will be assigned by creater
   OnCancel = function() end,
   sound = "levelup2",
   timeout = 10,
   whiledead = 1,
   hideOnEscape = 1
}

--[[
BuildItemActionMenu(itembutton, dewOptions, iteminfo)
Description:
  Called when the user right-clicks on an item in the "Loot distribution" window.
  This is the DKP system's opportunity to do things like assign a point value to the item, if desired.
Input:
  itembutton -- LootItem; lootitem class/table that's associated with the item passed.
  dewOptions -- table; dewOptions table to add the list to
  iteminfo -- ItemInfo table
Returns:
  boolean; true -- items were added to the list
           false -- no items were added to the list.
]]
function Recoil.prototype:BuildItemActionMenu(itembutton, dewOptions, iteminfo)
   if DKPmon.Looting:GetBidState() == 0 then -- Building item list
      if iteminfo.allowed then return false end
      if self.potentialitemvalues == nil then self.potentialitemvalues = {} end
      if self.potentialitemvalues[iteminfo.name] == nil then
	 self.potentialitemvalues[iteminfo.name] = {
	    value = 0, pool = 1
	 }
      end
      local mydb = DKPmon.DKP:GetDB("Recoil")
      dewOptions.args.Recoil = {
	 type = 'group',
	 name = L['Specify item value'],
	 desc = L['Specify the value of this item'],
	 args = {
	    assign = {
	       type = 'execute', name = L['Assign value'], desc = L['Assign this value to this item'],
	       func = function()
			 if self.potentialitemvalues[iteminfo.name] == 0 then DKPmon:Print(L["Cannot assign a value of zero"]); return end
			 StaticPopupDialogs["DKPMON_Recoil_CONFIRM_SETITEMVALUE"].text = 
			    string.format(L["Make %s worth %g points?"], 
					  iteminfo.link, self.potentialitemvalues[iteminfo.name].value)
			 StaticPopupDialogs["DKPMON_Recoil_CONFIRM_SETITEMVALUE"].OnAccept = 
			    function()
			       iteminfo.allowed = true
			       if mydb.itemlist == nil then mydb.itemlist = {} end
			       mydb.itemlist[iteminfo.name] = { value = self.potentialitemvalues[iteminfo.name].value }
			       self.potentialitemvalues[iteminfo.name] = nil
			       iteminfo.dkpinfo = { 
				  cost = mydb.itemlist[iteminfo.name].value, 
			       }
			    end
			 StaticPopup_Show("DKPMON_Recoil_CONFIRM_SETITEMVALUE")
			 dewdrop:Close()
		      end,
	       order = 1
	    },
	    setvalue = {
	       type = 'text', name = L['Set value'], desc = L['Set the number of points this item is worth'],
	       usage = '<value>',
	       get = function() return self.potentialitemvalues[iteminfo.name].value end,
	       set = function(v) self.potentialitemvalues[iteminfo.name].value = v end,
	       validate = function(v) local val = tonumber(v); if val == nil then return false end; return not (val < 0); end,
	       order = 3
	    }
	 }
      }
      return true
   end

   if DKPmon.Looting:GetBidState() == 1 then -- If bidding's open
      dewOptions.args.Recoil = {
	 type = 'text', name = L['Add/remove a bidder'], desc = L['Add, or remove, a player from the list of bidders for this item.'],
	 usage = '<name>', get = false,
	 validate = function(v)
		       -- Make sure the name's in the raid
		       local name = string.upper(string.sub(v,1,1))..string.lower(string.sub(v, 2))
		       return DKPmon.RaidRoster:IsPlayerInRaid(name)
		    end,
	 set = function(v)
		  local name = string.upper(string.sub(v,1,1))..string.lower(string.sub(v, 2))
		  DKPmon.Looting:ReceiveBid(name, { item = itembutton.id, dkp = { bidmodifier = math.floor(random()*100), cost = iteminfo.dkpinfo.cost } })
	       end
      }
      return true
   end
   return false
end

--[[
ProcessQueryConsole(bidname, bidclass)
Description:
  Build, and return, a message string to send regarding the point totals of the given bidname
Input:
  bidname -- name to look up the points for
Returns:
  String -- message to be displayed to the person who did the query
]]
function Recoil.prototype:ProcessQueryConsole(bidname)
   local tab = DKPmon.PointsDB:GetTable(bidname)
   if tab == nil then
      return L["You have no points."]
   end
   local reply = string.format("%s %g DKP;", L["Your points are:"], self:GetPlayerPoints(bidname, 1))
   return reply
end

--[[
GetNPools()
Description:
  Return the number of point pools being used by the DKP system
Input:
  None
Returns:
  Number.
]]
function Recoil.prototype:GetNPools()
   return 1
end

--[[
GetPoolName()
Description:
  Find out what the given pool number is called
Input:
  pool -- number in the range [1, GetNPools()]
Returns:
  string -- name by which to refer to the pool
]]
function Recoil.prototype:GetPoolName(pool)
   return "DKP"
end

--[[
PlaceBid(itembutton, bidder, dkpinfo, bidderlist, nbidders)
Description:
  Place, or remove, a bid for the given person on this item.
Input:
  bidder -- String; in-game name of the person bidding (i.e. not their bidname)
  dkpinfo -- information sent along for the DKP system to update this bid.
  bidderlist -- table; the list of bidders for this item. Each entry = { name = <name of person bidding>, dkpinfo = <information about the bid> }
  nbidders -- number; number of elements in the bidderlist table
Returns:
  boolean 
    nil = bid rejected
    false = bid removed
    true = bid accepted
]]
function Recoil.prototype:PlaceBid(itembutton, bidder, dkpinfo, bidderlist, nbidders)
   -- For Points as Currency, bid placement is a toggle; which means dkpinfo is nil
   -- If they're not in the bidderlist, then they get added. If they are already in the list, they get removed.
  
   -- Search the biddinglist to see if this person's already bid on this item   
   local i
   for i = 1, nbidders do
      if bidderlist[i].name == bidder then
	 -- Remove this element from the list
	 table.remove(bidderlist, i)
	 SendChatMessage(bidder.." has removed their bid for "..itembutton.iteminfo.link, "RAID")
	 return false
      end
   end
   -- Person wasn't in the list, so add them
   table.insert(bidderlist, { name = bidder, bidmodifier = dkpinfo.bidmodifier })
   SendChatMessage(bidder.." has placed a bid for "..itembutton.iteminfo.link..' @ '..dkpinfo.cost..' DKP (Roll: '..dkpinfo.bidmodifier..')', "RAID")
   return true
end

--[[
GetCost(winner, itemdkp, winnerdkp)
Description:
  Given the dkpinfo about an item, and the winner return a table containing the costs to charge the winner.
Input:
  winner -- string; name of the winner
  itemdkp -- table; same table returned from self:GetItemInfo()
  winnerdkp -- table; same table used in self:PlaceBid()
Returns:
  table  -- {  [<pool#>] = <number -- the cost to the pool>, ... }
]]
function Recoil.prototype:GetCost(winner, itemdkp, winnerdkp)
   return { [1] = itemdkp.cost }
end

--[[
DeductPoints(itemwinners)
Description:
  Deduct the points for won items.
Input:
  itemwinners -- table; { [i] = { winner = <string; raid name of the winner>, 
  item = <table; ItemInfo struct>,
  dkp = <table; return value of self:GetCost() for the won item> } } for i = 1.. num winners
Returns:
  None
]]
function Recoil.prototype:DeductPoints(itemwinners)
   local i, tab
   local mydb = DKPmon.DKP:GetDB("Recoil")
   if mydb.pointswaiting == nil then mydb.pointswaiting = {} end
   for i, tab in ipairs(itemwinners) do
      -- Deduct the points from the winner
      if tab.winner ~= L["Disenchant"] and tab.winner ~= L["Bank"] then -- We don't deduct points for disenchanting or banking
	 local wininfo = DKPmon.RaidRoster:GetPlayerInfo(tab.winner)
	 if wininfo == nil then
	    local msg = string.format(L["Error -- %s has never been in the raid! I cannot deduct points because I don't know enough about them. Please make note of the following deductions and do them manually:"], tab.winner)
	    local p, c
	    for p, c in pairs(tab.dkp) do
	       msg = string.format(L["%s\n%g from pool %d"], msg, c, p)
	    end
	    DKPmon:Print(msg)
	 else
	    local p, c
	    for p, c in pairs(tab.dkp) do
	       DKPmon.PointsDB:SpendPoints(wininfo.bidchar, tonumber(p), c)
	       DKPmon.Comm:SendToBidder("M", string.format(L["You have been charged %g points for %s."], c, tab.item.link), tab.winner)
	    end
	 end
         -- Add the value of the item to the list of points remaining to be awarded (Skipping if we DE or Banked the item)     
         if mydb.pointswaiting[tab.item.source] == nil then mydb.pointswaiting[tab.item.source] = { onlist = false } end
         local p, c
         for p, c in pairs(tab.dkp) do
	    if mydb.pointswaiting[tab.item.source][tonumber(p)] == nil then
	       mydb.pointswaiting[tab.item.source][tonumber(p)] = 0
	    end
	    mydb.pointswaiting[tab.item.source][tonumber(p)] = mydb.pointswaiting[tab.item.source][p] + tonumber(c)
         end
      end
   end
end

--[[
GetAwardFrame()
Description:
  Build, if required,  and return the subframe that will be attached to the points awarding frame to handle
  points awarding for this DKP system
Input:
  None
Returns:
  A frame
]]
function Recoil.prototype:GetAwardFrame()
   if self.awardframe then return self.awardframe end
   local f = CreateFrame("Frame", "DKPmonRecoilAwardFrame", nil)
   --   f:SetFrameLevel(6)
   f:SetWidth(200)
   f:SetHeight(45)
   self.awardframe = f
   
   DKPmon.FrameSkinner:BackdropFrame(f, {0, 0, 0, 0.7}, {0.7, 0.7, 0.7, 0.9} )
   
   DKPmon.FrameSkinner:Skin(f)
   
   local b = CreateFrame("Button", "DKPmonRecoilAwardFrameActionButton", f, "UIPanelButtonTemplate")
   f.selectbutton = b
   b:SetWidth(175); b:SetHeight(22)
   b:SetFrameLevel(6)
   b:SetText(L["Set points to award"])
   b:ClearAllPoints()
   b:SetPoint("TOP", f, "TOP", 0, -10)
   local Recoil = self
   b:SetScript("OnClick", function() Recoil:OnAwardButtonClick() end)
   b:Show()
   
   self.customaward = { pool = 1, amount = 0 }
   return self.awardframe
end


--[[
OnAwardButtonClick()
Description:
  Called when the user clicks on the button on our frame in the awarding points window
Input:
  None
Returns:
  None
]]
function Recoil.prototype:OnAwardButtonClick()
   if self.awardactionmenu == nil then
      local Recoil = self
      local dewtab = { type = 'group', args = {} }
      -- Add in the menu for specifying a custom number of points to award
      local custab = { type = 'group', name = L['Specify custom amount'], desc = L['Specify a custom number of points to award to everyone'], args = {}, order = 3 }
      custab.args.appendcurr = {
	 type = 'execute', name = L['Append custom'], desc = L['Append the currently specified custom amount to the list of points to be awarded.'],
	 func = function()
		   if Recoil.customaward.amount == 0 then return end
		   DKPmon.Awarding:AppendPointAward({ pool = Recoil.customaward.pool, amount = Recoil.customaward.amount, source = "Custom" })
		end,
	 order = 2
      }
      custab.args.amount = {
	 type = 'text', name = L['Specify points'], usage = "<number>", desc = L["Specify the number of points to award. This can be negative."],
	 get = function()
		  return string.format("%g", Recoil.customaward.amount)
	       end,
	 set = function(v)
		  Recoil.customaward.amount = tonumber(v)
	       end,
	 validate = function(v)
		       return tonumber(v) ~= nil
		    end,
	 input = false,
	 order = 4
      }
      dewtab.args.custom = custab
      
      self.awardactionmenu = dewtab
   end
   -- Add in options for adding waiting points from item distribution
   local mydb = DKPmon.DKP:GetDB("Recoil")
   local itemtab = { type = 'group', name = L['Points outstanding'], desc = L["Award points still waiting to be awarded from item distribution"], args = {}, order = 1 }
   local source, stab
   local numselected = DKPmon.Awarding:GetNumSelected()
   if mydb.pointswaiting == nil then
      mydb.pointswaiting = {}
   end
   if numselected == 0 then
      DKPmon:Print(L["Must have more than 0 players selected to award points to before you can select any outstanding points to be awarded."])
   else
      local addeditems = false
      for source, stab in pairs(mydb.pointswaiting) do
	 local s, tb = source, stab
	 addeditems = true
	 itemtab.args[source] = { 
	    type = 'execute', name = source, desc = string.format(L["Award points for %s"], source), 
	    func = function()
		      local pool, amt
		      for pool, amt in pairs(tb) do
			 if tonumber(pool) ~= nil then
			    DKPmon.Awarding:AppendPointAward({pool = tonumber(pool), amount = floor((amt/(numselected+1))*100+0.5)/100, source = s})
			 end
		      end
		      tb.onlist = true
		   end,
	 }
      end
      if addeditems then
	 self.awardactionmenu.args.pointstoaward = itemtab
      end
   end
   dewdrop:Open(self.awardframe.selectbutton, 'children', self.awardactionmenu, 'point', "TOP", 'relativepoint', "TOP")
end

--[[
OnPurgePointsList()
Description:
  Called from the points awarding routines when the user purges the points list.
Input:
Returns:
]]
function Recoil.prototype:OnPurgePointsList()
   local source, stab
   local mydb = DKPmon.DKP:GetDB("Recoil")
   for source, stab in pairs(mydb.pointswaiting) do
      stab.onlist = false
   end
end

--[[
PointsAwarded()
Description:
  Called from the points awarding routines _after_ all the points in its list have been awarded.
Input:
Returns:
]]
function Recoil.prototype:PointsAwarded()
   local source, stab
   local mydb = DKPmon.DKP:GetDB("Recoil")
   for source, stab in pairs(mydb.pointswaiting) do
      if stab.onlist then
	 mydb.pointswaiting[source] = nil
      end
      DKPmon:TableDelete(stab)
   end
end

--[[
GetFubarOptionsMenu()
Description:
  Return the options menu for this DKP system to be added to the fubar. This must be a valid Ace Options table, or nil
Input:
Returns:
  nil or an Ace Options table
]]
function Recoil.prototype:GetFubarOptionsMenu()
   if self.fubarmenu then return self.fubarmenu end
   local mydb = DKPmon.DKP:GetDB("Recoil")
   local tab = {
      type = 'group',
      name = L['Recoil DKP options'],
      desc = L['Options for the Recoil DKP System'],
      args = {
	 qualitythreshold = {
	    type = 'text',
	    name = L['Item quality threshold'],
	    desc = L['Set the threshold on item quality to automatically include in the item list for bidding on.'],
	    usage = '<number>',
	    get = function() return "p"..mydb.qualthreshold end,
	    set = function(v) mydb.qualthreshold = tonumber(string.sub(v,2)) end,
	    validate = { 
	       ["p0"] = string.format(L["|cff%sPoor|r"], DKPmon:rgbToHex(ITEM_QUALITY_COLORS[0])), 
	       ["p1"] = string.format(L["|cff%sCommon|r"], DKPmon:rgbToHex(ITEM_QUALITY_COLORS[1])),
	       ["p2"] = string.format(L["|cff%sUncommon|r"], DKPmon:rgbToHex(ITEM_QUALITY_COLORS[2])),
	       ["p3"] = string.format(L["|cff%sRare|r"], DKPmon:rgbToHex(ITEM_QUALITY_COLORS[3])),
	       ["p4"] = string.format(L["|cff%sEpic|r"], DKPmon:rgbToHex(ITEM_QUALITY_COLORS[4])),
	       ["p5"] = string.format(L["|cff%sLegendary|r"], DKPmon:rgbToHex(ITEM_QUALITY_COLORS[5])),
	       ["p6"] = string.format(L["|cff%sArtifact|r"], DKPmon:rgbToHex(ITEM_QUALITY_COLORS[6])),
	    },
	    order = 2
	 },
	 ctrt = {
	 	type = 'toggle',
	 	name = L['CT_RaidTracker Communication'],
	 	desc = L['Enable automatically inserting DKP costs into CT_RaidTracker'],
	 	get = function()
	 		return mydb.ctrt
	 	      end,
	 	set = function(v)
	 		mydb.ctrt = v
   			if (CT_RaidTracker_Options and mydb.ctrt == true) then
   				CT_RaidTracker_Options["AskCost"] = 7;
   				CT_RaidTracker_Options["GetDkpValue"] = 4;
   			elseif (CT_RaidTracker_Options and mydb.ctrt == false) then
   				CT_RaidTracker_Options["AskCost"] = 0;
   				CT_RaidTracker_Options["GetDkpValue"] = 0;
   			end
	 	      end,
	 	order = 1;
	 }
	 	
      }
   }   
   self.fubarmenu = tab
   return tab
end

--[[
ilvlDKP(item)
Description:
  Returns the DKP cost of the item
Input:
  item -- An item
Returns:
  Number -- A positive integer DKP value, or 0 if the value could not be calculated.
]]
function Recoil:ilvlDKP(item)
	-- Make sure we have an item
	if not item then return -1000,0 end
	
	local name,_,itemRarity,itemLevel,_,itemType,itemSubType,_,itemEquipLoc = GetItemInfo(item)
	
	-- Check if the item is in our static table
	if DKPMon_Recoil_Static[name] then
		return DKPMon_Recoil_Static[name]
	end      
		
	-- Check the item type and rarity	
	if (not ((itemType == "Armor" or itemType == "Weapon") and (itemRarity > 2 and  itemRarity < 6))) then
		return 0
	end

	-- Set DKP base cost
	local dkp_base = 0
	if (itemRarity == 3) then
		dkp_base = (itemLevel - 1.84) / 1.6
	elseif (itemRarity == 4) then
		dkp_base = (itemLevel - 1.3) / 1.3
	elseif (itemRarity == 5) then
		dkp_base = itemLevel
	end

	-- Set slot modifier
	local dkp_slot = 0
	if     (itemEquipLoc == "INVTYPE_HEAD") then
		dkp_slot = 1
	elseif (itemEquipLoc == "INVTYPE_NECK") then
		dkp_slot =  0.54
	elseif (itemEquipLoc == "INVTYPE_SHOULDER") then
		dkp_slot = 0.74
	elseif (itemEquipLoc == "INVTYPE_CHEST") then
		dkp_slot = 1
	elseif (itemEquipLoc == "INVTYPE_ROBE") then
		dkp_slot = 1
	elseif (itemEquipLoc == "INVTYPE_WAIST") then
		dkp_slot = 0.74
	elseif (itemEquipLoc == "INVTYPE_LEGS") then
		dkp_slot = 1
	elseif (itemEquipLoc == "INVTYPE_FEET") then
		dkp_slot = 0.74
	elseif (itemEquipLoc == "INVTYPE_WRIST") then
		dkp_slot = 0.54
	elseif (itemEquipLoc == "INVTYPE_HAND") then
		dkp_slot = 0.74
	elseif (itemEquipLoc == "INVTYPE_FINGER") then
		dkp_slot = 0.54
	elseif (itemEquipLoc == "INVTYPE_TRINKET") then
		dkp_slot = 0.68
	elseif (itemEquipLoc == "INVTYPE_CLOAK") then
		dkp_slot = 0.54
	elseif (itemEquipLoc == "INVTYPE_WEAPON") then
		dkp_slot = 1
	elseif (itemEquipLoc == "INVTYPE_SHIELD") then
		dkp_slot = 0.65
	elseif (itemEquipLoc == "INVTYPE_2HWEAPON") then
		dkp_slot = 1.5
	elseif (itemEquipLoc == "INVTYPE_WEAPONMAINHAND") then
		dkp_slot = 1
	elseif (itemEquipLoc == "INVTYPE_WEAPONOFFHAND") then
		dkp_slot = 1
	elseif (itemEquipLoc == "INVTYPE_HOLDABLE") then
		dkp_slot = 0.52
	elseif (itemEquipLoc == "INVTYPE_RANGED" or itemEquipLoc == "INVTYPE_RANGEDRIGHT" or itemEquipLoc == "INVTYPE_THROWN") then
		if (itemSubType == "Guns" or itemSubType == "Bows" or itemSubType == "Crossbows") then
			dkp_slot = 1.5
		else
			dkp_slot = 0.50
		end
	elseif (itemEquipLoc == "INVTYPE_RELIC") then
		dkp_slot = 0.30
	else
		dkp_slot = 0
	end

	return math.floor(dkp_base * dkp_slot * 10)
end

-- Hack to inject costs into CT_RaidTracker
if (HDKP_GetDKP) then 
	HDKP_GetDKP = HDKP_GetDKP_OLD
end

function HDKP_GetDKP(arg1, arg2, arg3, arg4)
	return Recoil:ilvlDKP(arg1)
end

-- Last, but not least, create a Recoil object and register it to DKPmon as a DKP system
local RecoilObj = Recoil:new()
DKPmon.DKP:Register(RecoilObj, "Recoil", L["Recoil DKP"])
